// 验证和错误处理工具函数

import type { Submission, GradingResult } from '@/types'
import { isValidSubmission, isValidGradingResult } from '@/types'

/**
 * 验证HTML代码的基本结构
 * @param code HTML代码字符串
 * @returns 验证结果和错误信息
 */
export function validateHTMLCode(code: string): { isValid: boolean; errors: string[] } {
  const errors: string[] = []
  
  if (!code || code.trim().length === 0) {
    errors.push('代码不能为空')
    return { isValid: false, errors }
  }
  console.log(code) 
  
  // 检查基本HTML结构
  if (!/<html[\s>]/i.test(code)) {
    errors.push('缺少 <html> 标签')
  }
  
  if (!/<head[\s>]/i.test(code)) {
    errors.push('缺少 <head> 标签')
  }
  
  if (!/<body[\s>]/i.test(code)) {
    errors.push('缺少 <body> 标签')
  }
  
  // 检查标签配对
  const openTags = code.match(/<[^/][^>]*>/g) || []
  const closeTags = code.match(/<\/[^>]*>/g) || []
  
  // 过滤掉自闭合标签（如 <meta />, <br />, <img /> 等）
  const regularOpenTags = openTags.filter(tag => !tag.endsWith('/>'))
  
  // 过滤掉DOCTYPE声明和注释
  const validOpenTags = regularOpenTags.filter(tag => 
    !tag.toLowerCase().startsWith('<!doctype') && 
    !tag.startsWith('<!--')
  )
  
  if (Math.abs(validOpenTags.length - closeTags.length) > 3) {
    errors.push('标签配对可能存在问题，请检查开闭标签')
  }
  
  return {
    isValid: errors.length === 0,
    errors
  }
}

/**
 * 安全地解析和验证提交数据
 * @param submissionData 原始提交数据
 * @returns 验证后的提交对象或null
 */
export function safeParseSubmission(submissionData: any): Submission | null {
  try {
    if (!isValidSubmission(submissionData)) {
      console.warn('Invalid submission data:', submissionData)
      return null
    }
    
    return {
      ...submissionData,
      score: submissionData.score ?? 0,
      grade: submissionData.grade ?? 'F',
      feedback: submissionData.feedback ?? ''
    }
  } catch (error) {
    console.error('Error parsing submission:', error)
    return null
  }
}

/**
 * 安全地解析评分结果
 * @param gradingData 原始评分数据
 * @returns 验证后的评分结果或默认值
 */
export function safeParseGradingResult(gradingData: any): GradingResult {
  if (!isValidGradingResult(gradingData)) {
    console.warn('Invalid grading result, using default:', gradingData)
    return {
      score: 0,
      maxScore: 100,
      details: {
        structure: { score: 0, maxScore: 30, feedback: '结构检查失败' },
        content: { score: 0, maxScore: 30, feedback: '内容检查失败' },
        quality: { score: 0, maxScore: 25, feedback: '质量检查失败' },
        creativity: { score: 0, maxScore: 15, feedback: '创新性检查失败' }
      },
      feedback: '评分过程中出现错误，请重试',
      grade: 'F'
    }
  }
  
  return gradingData
}

/**
 * 防抖函数
 * @param func 要防抖的函数
 * @param delay 延迟时间（毫秒）
 * @returns 防抖后的函数
 */
export function debounce<T extends (...args: any[]) => any>(
  func: T,
  delay: number
): (...args: Parameters<T>) => void {
  let timeoutId: number | undefined
  
  return (...args: Parameters<T>) => {
    if (timeoutId) {
      clearTimeout(timeoutId)
    }
    
    timeoutId = setTimeout(() => {
      func.apply(null, args)
    }, delay)
  }
}

/**
 * 节流函数
 * @param func 要节流的函数
 * @param delay 节流间隔（毫秒）
 * @returns 节流后的函数
 */
export function throttle<T extends (...args: any[]) => any>(
  func: T,
  delay: number
): (...args: Parameters<T>) => void {
  let lastCall = 0
  
  return (...args: Parameters<T>) => {
    const now = Date.now()
    
    if (now - lastCall >= delay) {
      lastCall = now
      func.apply(null, args)
    }
  }
}

/**
 * 安全的本地存储操作
 */
export const safeLocalStorage = {
  /**
   * 安全地获取本地存储数据
   * @param key 存储键
   * @param defaultValue 默认值
   * @returns 存储的值或默认值
   */
  getItem<T>(key: string, defaultValue: T): T {
    try {
      const item = localStorage.getItem(key)
      return item ? JSON.parse(item) : defaultValue
    } catch (error) {
      console.warn(`Failed to get localStorage item '${key}':`, error)
      return defaultValue
    }
  },
  
  /**
   * 安全地设置本地存储数据
   * @param key 存储键
   * @param value 要存储的值
   * @returns 是否成功
   */
  setItem<T>(key: string, value: T): boolean {
    try {
      localStorage.setItem(key, JSON.stringify(value))
      return true
    } catch (error) {
      console.warn(`Failed to set localStorage item '${key}':`, error)
      return false
    }
  },
  
  /**
   * 安全地移除本地存储数据
   * @param key 存储键
   * @returns 是否成功
   */
  removeItem(key: string): boolean {
    try {
      localStorage.removeItem(key)
      return true
    } catch (error) {
      console.warn(`Failed to remove localStorage item '${key}':`, error)
      return false
    }
  }
}

/**
 * 格式化文件大小
 * @param bytes 字节数
 * @returns 格式化后的文件大小字符串
 */
export function formatFileSize(bytes: number): string {
  if (bytes === 0) return '0 Bytes'
  
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

/**
 * 生成唯一ID
 * @returns 唯一标识符
 */
export function generateUniqueId(): string {
  return Date.now().toString(36) + Math.random().toString(36).substr(2)
}

/**
 * 深度克隆对象
 * @param obj 要克隆的对象
 * @returns 克隆后的对象
 */
export function deepClone<T>(obj: T): T {
  if (obj === null || typeof obj !== 'object') {
    return obj
  }
  
  if (obj instanceof Date) {
    return new Date(obj.getTime()) as unknown as T
  }
  
  if (obj instanceof Array) {
    return obj.map(item => deepClone(item)) as unknown as T
  }
  
  if (typeof obj === 'object') {
    const clonedObj = {} as { [key: string]: any }
    
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        clonedObj[key] = deepClone(obj[key])
      }
    }
    
    return clonedObj as T
  }
  
  return obj
}